package top.jle.wx.proxy.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import top.jle.jpa.basic.exception.BasicCustomException;
import top.jle.jpa.basic.exception.BasicExceptionCode;
import top.jle.jpa.basic.util.ExceptionUtils;
import top.jle.wx.proxy.annotation.AccessToken;
import top.jle.wx.proxy.exception.ExceptionCode;
import top.jle.wx.proxy.facade.BasicFacade;
import top.jle.wx.proxy.util.GlobalThreadLocalUtil;
import org.apache.commons.lang3.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.AsyncHandlerInterceptor;

import java.lang.reflect.Method;


@Component
@Slf4j
public class GlobalInterceptor  implements AsyncHandlerInterceptor {
    @Autowired
    @Lazy
    private BasicFacade basicFacade;
    @Value("${auth.token}")
    private String interfaceToken;
    @Value("${auth.token-header}")
    private String tokenHeader;
    @Override
    public boolean preHandle(@NonNull HttpServletRequest request,@NonNull HttpServletResponse response,@NonNull Object handler) {
        if(!(handler instanceof HandlerMethod handlerMethod)){
            return true;
        }
        String token = request.getHeader(tokenHeader);
        if(StringUtils.isBlank(token)){
            throw new BasicCustomException(BasicExceptionCode.AUTH_EMPTY_TOKEN);
        }
        if(!token.equals(interfaceToken)){
            throw new BasicCustomException(BasicExceptionCode.AUTH_TOKEN_INVALID);
        }
        String appId = request.getParameter("appId");
        if(StringUtils.isBlank(appId)){
            ExceptionUtils.throwInvalidParamException();
        }
        String secret = request.getParameter("secret");
        GlobalThreadLocalUtil.setAppId(appId);
        GlobalThreadLocalUtil.setSecret(secret);
        Method method=handlerMethod.getMethod();
        if(method.getDeclaringClass().isAnnotationPresent(AccessToken.class) || method.isAnnotationPresent(AccessToken.class)){
            if(StringUtils.isBlank(secret)){
                ExceptionUtils.throwInvalidParamException();
            }
            log.info("appId={},secret={}",appId,secret);
            String accessToken = basicFacade.getAccessToken();
            GlobalThreadLocalUtil.setAccessToken(accessToken);
        }

        return true;
    }

    @Override
    public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,@NonNull Object handler, Exception ex) throws Exception {
        GlobalThreadLocalUtil.clearAll();
        AsyncHandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}
